package com.ssy.lingxi.order.service.base;

import com.ssy.lingxi.common.model.dto.UserLoginCacheDTO;
import com.ssy.lingxi.common.response.Wrapper;
import com.ssy.lingxi.order.entity.OrderDO;
import com.ssy.lingxi.order.entity.OrderPaymentDO;
import com.ssy.lingxi.order.model.bo.OrderPayResultBO;
import com.ssy.lingxi.order.model.bo.OrderPaymentBO;
import com.ssy.lingxi.order.model.bo.OrderPaymentCheckBO;
import com.ssy.lingxi.order.model.bo.PayNodeBO;
import com.ssy.lingxi.order.model.constant.OrderPaymentCallbackStatusEnum;
import com.ssy.lingxi.order.model.dto.OrderReturnAmountDTO;
import com.ssy.lingxi.order.model.dto.PaymentCacheDTO;
import com.ssy.lingxi.order.model.vo.basic.request.OrderPaymentVO;
import com.ssy.lingxi.order.model.vo.basic.response.OrderPayTypeDetailVO;
import com.ssy.lingxi.order.model.vo.buyer.response.BuyerOrderPayNodeQueryVO;
import com.ssy.lingxi.order.model.vo.buyer.response.BuyerOrderPaymentDetailVO;
import com.ssy.lingxi.order.model.vo.buyer.response.BuyerPayResultDetailVO;
import com.ssy.lingxi.order.model.vo.vendor.response.VendorOrderPaymentDetailVO;

import java.util.List;

/**
 * 订单支付记录相关接口
 * @author 万宁
 * @version 2.0.0
 * @date 2021-07-20
 */
public interface IBaseOrderPaymentService {
    /**
     * 校验、保存订单支付记录，调用方要保存 OrderDO
     * @param order 订单
     * @param payType 订单支付方式
     * @param payChannel 订单支付渠道
     * @param payNodes 交易流程中设置的支付环节
     * @return 资金归集模式
     */
    Wrapper<OrderPaymentCheckBO> checkOrderPayment(OrderDO order, Integer payType, Integer payChannel, List<PayNodeBO> payNodes);

    /**
     * 校验、保存（积分兑换）订单支付记录，调用方要保存 OrderDO
     * @param order 订单
     * @param payType 订单支付方式
     * @param payChannel 订单支付渠道
     * @param payNodes 交易流程中设置的支付环节
     * @return 资金归集模式
     */
    Wrapper<Integer> checkPointsOrderPayment(OrderDO order, Integer payType, Integer payChannel, List<PayNodeBO> payNodes);

    /**
     * 校验、保存新增订单支付记录，调用方要保存OrderDO
     * @param order 订单
     * @param payNodes 供应商交易流程设置中的支付环节
     * @param payments 接口参数
     * @param isCreate 是否是新增，true-新增，false-修改
     * @return 校验结果
     */
    Wrapper<Void> checkOrderCreatePayment(OrderDO order, List<PayNodeBO> payNodes, List<OrderPaymentVO> payments, boolean isCreate);

    /**
     * 修改新增订单支付记录
     * @param order 订单
     * @param payments 接口参数
     * @return 校验结果
     */
    Wrapper<Void> updateOrderCreatePayment(OrderDO order, List<OrderPaymentVO> payments);

    /**
     * 根据订单中的订单总额，修改支付记录中的支付金额
     * @param order 订单
     * @return 修改结果
     */
    Wrapper<Void> vendorUpdatePaymentRate(OrderDO order);

    /**
     * 根据订单中的订单总额，修改支付记录中的支付金额
     * @param order 订单
     * @param payNodes 支付环节（其中的支付比例要为小数）
     * @return 修改结果
     */
    Wrapper<Void> vendorUpdatePaymentRate(OrderDO order, List<PayNodeBO> payNodes);

    /**
     * （转单）复制交易记录
     * @param order 订单
     * @param payNodes 供应商交易流程设置中的支付环节
     * @param payTypeDetails 上游供应商支付方式列表
     * @return 操作结果
     */
    Wrapper<Void> transferOrderPayments(OrderDO order, List<PayNodeBO> payNodes, List<OrderPayTypeDetailVO> payTypeDetails);

    /**
     * 修改B2B订单时，查询支付记录
     * @param order 订单
     * @return 查询结果
     */
    List<BuyerOrderPayNodeQueryVO> findBusinessOrderPayments(OrderDO order);

    /**
     * 采购商 - 订单支付记录列表
     * @param order 订单
     * @return 支付记录列表
     */
    List<BuyerOrderPaymentDetailVO> findBuyerOrderPayments(OrderDO order);

    /**
     * 供应商 - 订单支付记录列表
     * @param order 订单
     * @return 支付记录列表
     */
    List<VendorOrderPaymentDetailVO> findVendorOrderPayments(OrderDO order);

    /**
     * 平台后台 - 订单支付记录列表
     * @param order 订单
     * @return 支付记录列表
     */
    List<VendorOrderPaymentDetailVO> findPlatformOrderPayments(OrderDO order);

    /**
     * 订单创建后，判断、执行支付流程
     * @param order 订单
     * @return 执行结果
     */
    Wrapper<OrderPaymentBO> startOrderPaySerialTasks(OrderDO order);

    /**
     * 订单执行过程中，支付流程执行之前，判断是否跳过支付流程
     * @param order 订单
     * @return 执行结果
     */
    Wrapper<OrderPaymentBO> jumpOverOrderPaySerialTasks(OrderDO order);

    /**
     * 订单支付后，判断、执行支付流程，调用方要保存 List<OrderDO>
     * @param orders 订单列表
     * @param orderPayments 所有支付记录列表
     * @param batchNo     支付次数
     * @param paySuccess 是否支付成功
     * @param tradeNo    交易订单号
     * @return 执行结果
     */
    Wrapper<Void> execOrderPaySerialTasks(List<OrderDO> orders, List<OrderPaymentDO> orderPayments, Integer batchNo, boolean paySuccess, String tradeNo);

    /**
     * 采购商，订单支付
     * @param loginUser 登录用户
     * @param orders 订单列表
     * @param fundMode 资金归集模式
     * @param batchNo 支付次数
     * @param payType 支付方式
     * @param payChannel 支付渠道
     * @param vouchers 支付凭证列表
     * @param payPassword 支付密码
     * @param weChatCode 微信小程序支付时的小程序登录凭证
     * @param returnUrl  支付后的跳转链接
     * @return 支付结果
     */
    Wrapper<OrderPayResultBO> buyerPay(UserLoginCacheDTO loginUser, List<OrderDO> orders, Integer fundMode, Integer batchNo, Integer payType, Integer payChannel, List<String> vouchers, String payPassword, String weChatCode, String returnUrl);

    /**
     * 查询支付结果
     * @param tradeNo 交易单号
     * @return 支付结果
     */
    Wrapper<BuyerPayResultDetailVO> findPayResult(String tradeNo);

    /**
     * 订单支付回调，通过OpenFeign接口回调
     * @param orders 订单列表
     * @param paymentCache 支付缓存信息
     * @param paySuccess 是否支付成功
     * @return 支付结果
     */
    Wrapper<Void> buyerPayCallback(List<OrderDO> orders, PaymentCacheDTO paymentCache, Boolean paySuccess);

    /**
     * 订单支付回调，通过消息队列回调
     * @param orderIds 订单Id列表
     * @param batchNo  支付次数
     * @param tradeNo  订单服务生成的支付号
     * @param callbackStatus 支付状态
     * @param userName 用户姓名
     * @param organizationName 用户组织机构名称
     * @param jobTitle 职位
     * @return 支付结果
     */
    Wrapper<Void> buyerPayCallback(List<Long> orderIds, Integer batchNo, String tradeNo, OrderPaymentCallbackStatusEnum callbackStatus, String userName, String organizationName, String jobTitle);

    /**
     * 供应商 - 确认支付结果
     * @param order 订单
     * @param batchNo 支付批次
     * @param agree 确认结果，0-确认未支付，1-确认已经支付
     * @return 操作结果
     */
    Wrapper<Void> vendorConfirmPayment(OrderDO order, Integer batchNo, Integer agree);

    /**
     * 售后服务 - 退货 - 修改支付次数的金额
     * @param orders        订单列表
     * @param returnAmounts 订单Id及退款金额
     * @return 操作结果
     */
    Wrapper<Void> batchUpdateOrderPayments(List<OrderDO> orders, List<OrderReturnAmountDTO> returnAmounts);

    /**
     * 拼团订单退款
     * @param order 订单
     * @return 退款结果
     */
    Wrapper<Void> groupOrderRefund(OrderDO order);

    /**
     * 订单退款
     * @param order 订单
     * @param orderPayment 要退款的支付记录
     * @param remark 备注说明
     * @return 退款结果
     */
    Wrapper<Void> orderRefund(OrderDO order, OrderPaymentDO orderPayment, String remark);

    /**
     * 更新支付记录的结算状态
     * @param paymentIds 支付记录
     * @param settlementStatus 结算状态
     * @return 更新结果
     */
    Wrapper<Void> updatePaymentSettlementStatus(List<Long> paymentIds, Integer settlementStatus);

    /**
     * （调用支付服务接口）查询支付状态
     * @param payChannel 支付渠道
     * @param tradeNo    交易号
     * @param orderIds   订单Id列表
     * @param paymentIds 支付记录列表
     * @return 查询结果
     */
    Wrapper<OrderPaymentCallbackStatusEnum> findPaymentStatus(Integer payChannel, String tradeNo, List<Long> orderIds, List<Long> paymentIds);
}
